package dfbz.com.dao.base;

import dfbz.com.annotation.Filed;
import dfbz.com.annotation.Table;
import dfbz.com.model.User;
import dfbz.com.utils.JDBCUtil;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * 提供基本的增、删、改、查方法
 */

public class BaseDao<T>{


    public List<T>  loadStudent(Class<User> aClass) {
        Table table = aClass.getAnnotation(Table.class);
        List<T> list = new ArrayList<>();
        if (table!=null){
            String tableName = table.value();
            String sql = "select*from "+tableName;

            Connection connection = null;
            PreparedStatement statement = null;
            ResultSet resultSet = null;


            try {
                connection = JDBCUtil.getConnection();
                statement = connection.prepareStatement(sql);
                resultSet = statement.executeQuery();

                while (resultSet.next()) {
                    //得到这个类的所有字段，调用set的方法
                    Object obj =  aClass.newInstance();
                    Field[] fields = aClass.getDeclaredFields();
                    for (Field field : fields) {
                        String fieldName = field.getName();
                        if (field.isAnnotationPresent(Filed.class)) {
                            Filed anno = field.getAnnotation(Filed.class);
                           String fieldName2 = anno.value();
                            Object value2 = resultSet.getObject(fieldName2);
                            String methodName = "set"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);
                            Method method = aClass.getDeclaredMethod(methodName,field.getType());
                            method.invoke(obj, value2);
                        }else {
                            Object value = resultSet.getObject(fieldName);
                            String methodName = "set"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);
                            Method method = aClass.getDeclaredMethod(methodName,field.getType());
                            method.invoke(obj, value);
                        }
                    }
                    list.add((T)obj);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                JDBCUtil.close(resultSet, statement, connection);
            }
        }
        return list;

    }


    public void add(Object obj) {
        Class<?> aClass = obj.getClass();
        Table table = aClass.getDeclaredAnnotation(Table.class);
        if (table!=null){
            String tableName = table.value();
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append("insert into ").append(tableName).append(" values(");
            Connection connection = null;
            PreparedStatement statement = null;
            ResultSet resultSet = null;

            try {
                Field[] fields = aClass.getDeclaredFields();

                for (int i = 1; i <= fields.length; i++) {
                    if (i == fields.length){
                        stringBuilder.append("?)");
                    }else {
                        stringBuilder.append("?,");
                    }
                }
                connection = JDBCUtil.getConnection();
                statement = connection.prepareStatement(stringBuilder.toString());
                //获得对象的所有字段，设置？的值
                int count = 0;
                for (Field field : fields) {
                    String fieldName = field.getName();
                    //获得get的方法
                    String methodName = "get"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);
                    Method method = aClass.getDeclaredMethod(methodName);
                    //执行方法
                    Object value = method.invoke(obj);
                    statement.setObject(++count, value);
                }

                statement.executeUpdate();

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                JDBCUtil.close(resultSet, statement, connection);
            }
        }

    }




    public void delete(Object id,Class<T> aClass) {
        Table table = aClass.getDeclaredAnnotation(Table.class);

        if (table!=null){
            String tableName = table.value();
            String sql = "delete from "+tableName+" where id = ? ";

            Connection connection = null;
            PreparedStatement statement = null;
            ResultSet resultSet = null;

            try {
                connection = JDBCUtil.getConnection();
                statement = connection.prepareStatement(sql);
                statement.setObject(1, id);
                statement.executeUpdate();

            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                JDBCUtil.close(resultSet, statement, connection);
            }
        }

    }



    public void update(T t) {
        Class<?> aClass = t.getClass();
        Table table = aClass.getDeclaredAnnotation(Table.class);
        if (table!=null){
            String tableName = table.value();

            StringBuilder sql = new StringBuilder();
            sql.append("update ").append(tableName).append(" set id = ?,");
            Field[] fields = aClass.getDeclaredFields();
            try {
                for (Field field : fields) {
                    String fieldName = field.getName();
                    if (!fieldName.equals("id")){
                        //获得get的方法
                        String methodName = "get"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);
                        Method method = aClass.getDeclaredMethod(methodName);
                        //System.out.println("得到的方法名："+method.getName());

                        //执行方法___obj什么时候为空？？？--obj都为null
                        Object obj = method.invoke(t);
                        if (obj!=null){
                            sql.append(fieldName).append(" = ?,");
                        }
                    }
                }
            }  catch (Exception e) {
                e.printStackTrace();
            }

            sql.delete(sql.lastIndexOf(","), sql.length());
            sql.append(" where id = ?");

            Connection connection = null;
            PreparedStatement statement = null;
            ResultSet resultSet = null;

            try {
                connection = JDBCUtil.getConnection();
                statement = connection.prepareStatement(sql.toString());
                int count = 0;
                Method getId = aClass.getDeclaredMethod("getId");
                Object o = getId.invoke(t);
                statement.setObject(++count, o);

                for (Field field : fields) {
                    String fieldName = field.getName();
                    if (!fieldName.equals("id")){
                        //获得get的方法
                        String methodName = "get"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);
                        Method method = aClass.getDeclaredMethod(methodName);
                        //get方法返回的结果是这个字段的设置值
                        Object obj = method.invoke(t);
                        if (obj!=null){
                            statement.setObject(++count, obj);
                        }
                    }
                }
                statement.setObject(++count, o);

                statement.execute();

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                JDBCUtil.close(resultSet, statement, connection);
            }

        }

    }


    public T get(Object id,Class<T> aClass) {
        Table table = aClass.getDeclaredAnnotation(Table.class);
        if (table!=null){
            String tableName = table.value();
            String sql = "select * from "+tableName+" where id = ? ";

            Connection connection = null;
            PreparedStatement statement = null;
            ResultSet resultSet = null;
            T t = null;

            try {
                connection = JDBCUtil.getConnection();
                statement = connection.prepareStatement(sql);
                statement.setObject(1, id);
                resultSet = statement.executeQuery();


                if (resultSet.next()) {
                    Field[] fields = aClass.getDeclaredFields();
                    t = aClass.newInstance();
                    for (Field field : fields) {
                        String fieldName = field.getName();
                        if (field.isAnnotationPresent(Filed.class)) {
                            Filed anno = field.getAnnotation(Filed.class);
                            String fieldName2 = anno.value();
                            Object value2 = resultSet.getObject(fieldName2);
                            String methodName = "set"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);
                            Method method = aClass.getDeclaredMethod(methodName,field.getType());
                            method.invoke(t, value2);
                        }else {
                            Object value = resultSet.getObject(fieldName);

                            //得到set的方法
                            String methodName = "set"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);
                            Method method = aClass.getDeclaredMethod(methodName,field.getType());
                            //执行get方法
                            method.invoke(t, value);
                        }
                    }
                }
                return t;

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                JDBCUtil.close(resultSet, statement, connection);
            }
        }
        return null;
    }



    public void deleteAll(Object[] ids,Class<T> aClass) {
        Table table = aClass.getDeclaredAnnotation(Table.class);
        if (table!=null) {
            String tableName = table.value();

            StringBuilder sql = new StringBuilder();
            sql.append("delete from ").append(tableName).append(" where id = ?");
            for (int i = 1; i < ids.length; i++) {
                sql.append("||id = ?");
            }
            Connection connection = null;
            PreparedStatement statement = null;
            ResultSet resultSet = null;

            try {
                connection = JDBCUtil.getConnection();
                statement = connection.prepareStatement(sql.toString());
                statement.setObject(1, ids[0]);
                for (int i = 1; i < ids.length; i++) {

                    statement.setObject(i + 1, ids[i]);
                }

                statement.executeUpdate();

            } catch (SQLException e) {
                e.printStackTrace();
            } finally {
                JDBCUtil.close(resultSet, statement, connection);
            }
        }




    }
}
